Angular async pipe
In this tutorial, we shall see how to use async pipe to load content from a promise and the observable without subscribing to the observable.
Create a new angular project
First lets create an angular application using the following angular cli command.
ng new async-application
Setup loading data from promise in AppComponent
Once the application is created, open the app.component.ts
file and add the following code.
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
welcomeMessage = 'Welcome to ReadersBuddy';
title = 'angular-practise';
welcomeMessageFromPromise: Promise<string>;
constructor() {}
ngOnInit(): void {
}
}
In the above code, we have create a parameter welcomeMessage
which contains the static welcome string Welcome to ReadersBuddy
. Next we create a welcomeMessageFromPromise
parameter to hold the promise that returns the welcome message.
Create a function with name loadWelcomeMessageFromPromise
that returns a promise with welcome message after 2 seconds. This is done using setTimeout
javascript function.
loadWelcomeMessageFromPromise(): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => {
return resolve(this.welcomeMessage);
}, 2000);
});
}
Next, in ngOnInit()
function call the loadWelcomeMessageFromPromise()
function and assign it to variable welcomeMessageFromPromise
.
The final coding will look as below.
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
welcomeMessage = 'Welcome to ReadersBuddy';
title = 'angular-practise';
welcomeMessageFromPromise: Promise<string>;
constructor() {}
ngOnInit(): void {
this.welcomeMessageFromPromise = this.loadWelcomeMessageFromPromise();
}
loadWelcomeMessageFromPromise(): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => {
return resolve(this.welcomeMessage);
}, 2000);
});
}
}
Open the app.component.ts
file and add the following line.
<h1>{{ welcomeMessageFromPromise | async}}</h1>
Usually one can get the value from the promise is success callback function. We will receive a value from the promise after 2 seconds. To load the asynchronous value we will be using pipe(|
) symbol followed by the async
keyword.
When you run the application using ng serve --o
and when the output is rendered it will display welcome message after 2 seconds.
Setup loading data from observable in AppComponent
In the second part, lets load the value from Observable
after 2 seconds.
Open the app.component.ts file and declare the variable welcomeMessageFromObservable
and create a function loadWelcomeMessageFromObservable and add the code as below.
loadWelcomeMessageFromObservable(): Observable<string>{
return timer(2000).pipe(
map((value) => this.welcomeMessage),
);
}
The loadWelcomeMessageFromObservable
function will return an observable
after 2 seconds. Use the timer()
rxjs operator to take time in milliseconds as first parameter and return an observable
. We provide 2000 as the parameter which means 2s.
Now it will be active only after 2 seconds
and then we interpret the response with map operator and return the welcomeMessage value.
The final code of app.component.ts
file will look like below.
import { Component, OnInit } from '@angular/core';
import { Observable, of, timer } from 'rxjs';
import {map} from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
welcomeMessage = 'Welcome to ReadersBuddy';
title = 'angular-practise';
welcomeMessageFromPromise: Promise<string>;
welcomeMessageFromObservable;
constructor() {}
ngOnInit(): void {
this.welcomeMessageFromPromise = this.loadWelcomeMessageFromPromise();
this.welcomeMessageFromObservable = this.loadWelcomeMessageFromObservable();
}
loadWelcomeMessageFromPromise(): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => {
return resolve(this.welcomeMessage);
}, 2000);
});
}
loadWelcomeMessageFromObservable(): Observable<string>{
return timer(2000).pipe(
map((value) => this.welcomeMessage),
);
}
}
Now open the app.component.ts file and update the code to look like below.
<h1>{{ welcomeMessageFromPromise | async}}</h1>
<h1>{{welcomeMessageFromObservable | async}}</h1>
Run the application again using
ng serve --o
You will see 2 welcome message after 2 seconds.
Async operator to load data returned by api call
Now let's see how to load the response from the api asynchronously.
Setup HttpService to handle api calls
Create a service to perform api call. Let's create a service with the following angular cli command.
ng g s services/http
Open the http.service.ts
file in services folder and modify the code as below.
import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class HttpService {
constructor(private http: HttpClient) { }
getApi(url: string): Observable<any> {
return this.http.get(url).pipe(
map(response => {
return response['data'];
})
);
}
}
We have imported the HttpClient
to the constructor to make api call. Now we create a function named getApi
which takes the url as parameter and returns the response as the observable.
Using the get
function we make api call and transform the data using the map
operator inside the pipe function.
Now inject the HttpService
to the app.component.ts
file and also create a variable $users
of type Observable.
Next create a function getUsers()
that calls the getApi()
function to get the users from the api call.
constructor(private httpService: HttpService) {}
...
...
...
getUsers(): Observable<any> {
return this.httpService.getApi(this.gerUsersUrl);
}
The final app.component.ts
file looks as below.
import { Component, OnInit } from '@angular/core';
import { Observable, of, timer } from 'rxjs';
import {map} from 'rxjs/operators';
import {HttpService} from './services/http.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
welcomeMessage = 'Welcome to ReadersBuddy';
gerUsersUrl = 'https://reqres.in/api/users?page=2';
welcomeMessageFromPromise: Promise<string>;
welcomeMessageFromObservable;
$users: Observable<any>;
constructor(private httpService: HttpService) {}
ngOnInit(): void {
this.welcomeMessageFromPromise = this.loadWelcomeMessageFromPromise();
this.welcomeMessageFromObservable = this.loadWelcomeMessageFromObservable();
this.$users = this.getUsers();
}
loadWelcomeMessageFromPromise(): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => {
return resolve(this.welcomeMessage);
}, 2000);
});
}
loadWelcomeMessageFromObservable(): Observable<string>{
return timer(2000).pipe(
map((value) => this.welcomeMessage),
);
}
getUsers(): Observable<any> {
return this.httpService.getApi(this.gerUsersUrl);
}
}
Now open the app.component.html
file and add the following code the get the users list from the api asynchronously.
<h1>{{ welcomeMessageFromPromise | async}}</h1>
<h1>{{welcomeMessageFromObservable | async}}</h1>
<ul>
<li *ngFor="let user of $users | async">
{{user['first_name']}}
</li>
</ul>
This will list the users returned by the api.
The main advantage of using async
pipe is that we no need to subscribe
to the observable, it will be done automatically by the async pipe. We no need to worry about unsubscribing
the observable.